package com.ygy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.ygy.entity.Comments;
import com.ygy.entity.Users;
import com.ygy.entity.VO.CommentVo;
import com.ygy.mapper.CommentsMapper;
import com.ygy.mapper.UsersMapper;
import com.ygy.service.ICommentsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 留言评论表 服务实现类
 * </p>
 *
 * @author Ye
 * @since 2024-03-14
 */
@Service
public class CommentsServiceImpl extends ServiceImpl<CommentsMapper, Comments> implements ICommentsService {

    @Autowired
    UsersMapper usersMapper;
    //保存留言
    @Override
    public Boolean saveComment(Comments comment) {
         boolean save = save(comment);
        return save;
    }

    // 返回 评论列表
    @Override
    public List<CommentVo> getCommentService(Integer productId) {
      //1. 获取留言表里面productId等于传进来的productId
       QueryWrapper<Comments> allwrapper = new QueryWrapper<>();
        allwrapper.eq("product_id",productId);
        //所有留言列表
        List<Comments> allList = list(allwrapper);


            //遍历所有评论集合，复制到 评论视图返回
            ArrayList<CommentVo> commentVos = new ArrayList<>(); //留言视图返回集合
            for (Comments comments : allList){
                CommentVo commentVo = new CommentVo();
                BeanUtils.copyProperties(comments,commentVo);//前者复制给后者
                //重新给用户名和用户头像复制保持最新数据展示
                Integer userId = comments.getUserId();
                Users users = usersMapper.selectById(userId);
                commentVo.setUsername(users.getUsername());
                commentVo.setAvatar(users.getAvatar());
                commentVo.setCreatedAt(comments.getCreatedAt());//时间
                commentVo.setContent(comments.getContent());//内容
                commentVos.add(commentVo);

            }
//        System.out.println("打印输出commentVos"+commentVos);

             ArrayList<CommentVo> com = new ArrayList<>(); // 最终集合

        /**
         *评论id得为String 因为要与键值对形式存进map集合
         */
             HashMap<String, CommentVo> map = new HashMap<>();//保存所有评论
        //2.com集合存储一级留言
       // System.out.println("====================================================================");
       // System.out.println(commentVos);
            for (CommentVo comments : commentVos){//遍历每一条评论
                if ("0".equals(comments.getParentId())){
                    //一级评论
                    com.add(comments);
                }
                map.put(comments.getCommentId(),comments); //所有评论 id:评论对象
            }

         //  System.out.println("打印输出map"+map);
//        System.out.println("输出com1"+com);
       // System.out.println("输出com1==================================================================");

            //3.com集合内顶级评论 存储所有包含的子级评论
            for (CommentVo comments : commentVos){// 遍历每一条评论
                if (!"0".equals(comments.getParentId())){   // 非顶级评论，既第一子级、第二子级等等评论

                    //获取所有父级留言(如 a->b, b->c, c->d, d="0")
                    CommentVo parent = map.get(comments.getParentId());

                        if (parent == null ){
                            continue;//跳出本次循环
                        }

                        if (parent.getCommentId().equals(comments.getCommentId())){
                                continue;
                        }
                    // 所有父级存储子级 （b(reply[b]), c(replay[b(reply[a])]) ....）
                        parent.getReply().add(comments);
//                    System.out.println("输出parent"+parent);
//                    System.out.println("=====================================");
                }

            }

        // 结果是 顶级包含子级，子级包含孙级....，层次嵌套，
        // 但是我们想返回的是 父级>子级（包含所有子子孙孙） 两层
        // 组装好的评论数据

//        System.out.println("输出com2"+com);

        List<CommentVo> formatList = getFormat(com);
       // System.out.println("输出formatList"+formatList);
       // System.out.println("===========+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        return formatList;
    }


    // 存储 新组装好的 子级（子子孙孙） 数据集合
    ArrayList<CommentVo> newReplys = new ArrayList<>();
    /**
     * 重新组装评论集合，使其只有两层 顶级评论>第一子级评论（包含子级和子子孙孙）
     * @param com
     * @return
     */
    public List<CommentVo> getFormat(List<CommentVo> com){

        for (CommentVo comments : com) { // 遍历顶点集合
            // 获取顶点 子级集合
            List<CommentVo> replys = comments.getReply();
            for (CommentVo comment : replys) { // 遍历第一级（子级）回复集合  ( for(:) 只有集合元素>0才会进入)
                newReplys.add(comment); // 存储第一级子评论
                recursively(comment); // 递归子级评论
            }
            comments.setReply(newReplys); // 重新设置子级（包含子子孙孙）
            comments.setCommentNum(newReplys.size()); // 低级评论回复数
            // 新建（或清除）组装集合，避免下一轮顶点集合组装有数据
            newReplys = new ArrayList<>();
        }
//        System.out.println("输出com"+com);
        return com;
    }
    /**
     * 递归子级评论，返回顶级评论下 所有子代 都放到第一子级评论中
     *
     */
    private void recursively(CommentVo comment){
//        System.out.println("输出进入reply");
        List<CommentVo> replys = comment.getReply(); // 第二子级集合
        if (replys.size()>0){ // 存在评论
            for (CommentVo reply : replys) {
                newReplys.add(reply); // 存储
                if (reply.getReply().size()>0){
                    recursively(reply); // 递归
                }

            }

        }

    }

}
